#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
PostgreSQL基础模块
提供安装、卸载和初始化功能
"""

import os
import sys
import re
from typing import Optional

from ...core.utils import (
    logger,
    run_command, 
    detect_postgresql_version,
    get_service_name,
    is_windows,
    confirm_action,
    get_input_with_default
)
from ...core import config

class PostgresqlBase:
    """PostgreSQL数据库基础功能类"""
    
    def __init__(self):
        # 初始化时获取当前安装的PostgreSQL版本
        self.pg_version = detect_postgresql_version()
        self.config_path = f"/etc/postgresql/{self.pg_version}/main/" if self.pg_version else None
        self.bin_path = f"/usr/lib/postgresql/{self.pg_version}/bin" if self.pg_version else None
        
    def get_bin_path(self, command: str) -> str:
        """获取PostgreSQL命令的完整路径"""
        if is_windows():
            # Windows上命令通常在PATH中
            return command
        else:
            # Linux上可能需要完整路径
            if self.bin_path:
                return os.path.join(self.bin_path, command)
            return command
    
    def install(self):
        """安装PostgreSQL数据库"""
        version_input = get_input_with_default("输入要安装的PostgreSQL版本", "")

        logger.info("正在安装curl和ca证书，并导入PostgreSQL存储库签名密钥")
        run_command(["sudo", "apt", "install", "-y", "curl", "ca-certificates"])
        run_command(["sudo", "install", "-d", "/usr/share/postgresql-common/pgdg"])
        run_command([
            "sudo", "curl", "-o", "/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc",
            "--fail", "https://www.postgresql.org/media/keys/ACCC4CF8.asc"
        ])

        logger.info("正在配置PostgreSQL存储库")
        run_command([
            "sudo", "sh", "-c",
            'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] '
            'https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
        ])

        logger.info("正在更新包列表")
        run_command(["sudo", "apt", "update"])

        try:
            if not version_input:
                logger.info("正在安装PostgreSQL的最新版本")
                run_command(["sudo", "apt", "-y", "install", "postgresql"])
            else:
                logger.info(f"正在安装PostgreSQL版本 {version_input}")
                run_command(["sudo", "apt", "-y", "install", f"postgresql-{version_input}"])
            
            # 安装完成后更新版本信息
            self.pg_version = detect_postgresql_version()
            self.config_path = f"/etc/postgresql/{self.pg_version}/main/" if self.pg_version else None
            self.bin_path = f"/usr/lib/postgresql/{self.pg_version}/bin" if self.pg_version else None
            
            # 配置环境变量
            self.configure_environment(self.pg_version)
            
            logger.info(f"PostgreSQL {self.pg_version} 安装成功")
        except Exception as e:
            logger.error(f"安装PostgreSQL失败: {e}")
    
    def configure_environment(self, pg_version: str):
        """配置PostgreSQL环境变量"""
        bashrc_path = os.path.expanduser("~/.bashrc")
        profile_path = "/etc/profile"
        pg_bin_path = f"/usr/lib/postgresql/{pg_version}/bin"

        # 检查.bashrc中是否已存在PostgreSQL路径
        try:
            with open(bashrc_path, "r") as bashrc_file:
                bashrc_content = bashrc_file.read()
                if pg_bin_path not in bashrc_content:
                    logger.info("正在为PostgreSQL配置.bashrc环境")
                    with open(bashrc_path, "a") as bashrc_file_append:
                        bashrc_file_append.write(f'\n# Add PostgreSQL {pg_version} to PATH\n')
                        bashrc_file_append.write(f'export PATH=$PATH:{pg_bin_path}\n')
                    # 使用修复后的run_command处理source命令
                    if not is_windows():
                        run_command(["source", bashrc_path], shell=True)
                    else:
                        logger.info("Windows环境下，环境变量设置可能需要重启才能生效")
                else:
                    logger.info(f"PostgreSQL {pg_version} 路径已在.bashrc中")
        except Exception as e:
            logger.error(f"配置.bashrc时出错: {e}")

        # Windows环境下，通过系统方法设置环境变量
        if is_windows():
            try:
                import winreg
                with winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_ALL_ACCESS) as key:
                    path_value = winreg.QueryValueEx(key, "Path")[0]
                    if pg_bin_path not in path_value:
                        new_path = f"{path_value};{pg_bin_path}"
                        winreg.SetValueEx(key, "Path", 0, winreg.REG_EXPAND_SZ, new_path)
                        logger.info(f"已将 {pg_bin_path} 添加到系统PATH中")
            except Exception as e:
                logger.error(f"配置Windows环境变量时出错: {e}")
        # 否则，配置Linux的/etc/profile
        else:
            try:
                with open(profile_path, "r") as profile_file:
                    profile_content = profile_file.read()
                    if pg_bin_path not in profile_content:
                        logger.info("正在为PostgreSQL配置/etc/profile环境")
                        run_command([
                            "sudo", "sh", "-c",
                            f'echo "\n# Add PostgreSQL {pg_version} to PATH for all users\nexport PATH=\\$PATH:{pg_bin_path}\n" >> {profile_path}'
                        ])
                    else:
                        logger.info(f"PostgreSQL {pg_version} 路径已在/etc/profile中")
            except Exception as e:
                logger.error(f"配置/etc/profile时出错: {e}")

        # 测试pg_ctl是否可用
        try:
            result = run_command([f"{pg_bin_path}/pg_ctl", "--version"], capture_output=True)
            logger.info(f"pg_ctl现在可用: {result.stdout.strip()}")
        except Exception:
            logger.warning("pg_ctl命令不可用，请检查配置")
    
    def uninstall(self):
        """卸载PostgreSQL数据库"""
        if not confirm_action("确定要卸载PostgreSQL吗？此操作将删除所有数据库数据", False):
            logger.info("已取消卸载PostgreSQL")
            return
            
        service_name = get_service_name(self.pg_version)
        logger.info("正在卸载PostgreSQL")
        
        try:
            run_command(["sudo", "systemctl", "stop", service_name])
            run_command(["sudo", "apt", "purge", "-y", "postgresql*"])
            run_command(["sudo", "apt", "autoremove", "-y"])
            run_command(["sudo", "rm", "-rf", "/etc/postgresql", "/var/lib/postgresql"])
            
            logger.info("PostgreSQL卸载完成")
            
            # 重置状态
            self.pg_version = None
            self.config_path = None
            self.bin_path = None
        except Exception as e:
            logger.error(f"卸载PostgreSQL时出错: {e}")
            
    def create_new_cluster(self):
        """创建新的PostgreSQL集群，设置默认数据目录"""
        import shutil
        
        datadir = get_input_with_default("请输入数据库数据目录", "/home/data")
        
        # 检查目录是否可写
        if not os.path.exists(datadir):
            try:
                os.makedirs(datadir)
            except Exception as e:
                logger.error(f"创建数据目录 {datadir} 时出错: {e}")
                return
        
        # 停止现有的PostgreSQL集群
        try:
            logger.info("正在停止PostgreSQL集群...")
            run_command(["sudo", "pg_ctlcluster", self.pg_version, "main", "stop"])
            logger.info("PostgreSQL集群已成功停止")
        except Exception as e:
            logger.error(f"停止PostgreSQL集群时出错: {e}")
            return
            
        # 删除现有的PostgreSQL集群
        try:
            logger.info("正在删除PostgreSQL集群...")
            run_command(["sudo", "pg_dropcluster", self.pg_version, "main", "--stop"])
            logger.info("PostgreSQL集群已成功删除")
        except Exception as e:
            logger.error(f"删除PostgreSQL集群时出错: {e}")
            return
            
        # 询问是否移动默认数据文件
        move_files = confirm_action(
            f"是否要移动默认的 /var/lib/postgresql/{self.pg_version}/main 中的所有文件到指定的数据目录?",
            False
        )
        
        if move_files:
            default_data_dir = f"/var/lib/postgresql/{self.pg_version}/main"
            try:
                logger.info(f"正在移动文件从 {default_data_dir} 到 {datadir}...")
                if os.path.exists(default_data_dir):
                    shutil.move(default_data_dir, datadir)
                    logger.info("文件移动成功")
                else:
                    logger.error(f"默认数据目录 {default_data_dir} 不存在")
                    return
            except Exception as e:
                logger.error(f"移动文件时出错: {e}")
                return
                
        # 创建新的PostgreSQL集群
        try:
            logger.info("正在创建新的PostgreSQL集群...")
            run_command([
                "sudo", "pg_createcluster",
                "--datadir", datadir,
                self.pg_version, "main"
            ])
            logger.info("新的PostgreSQL集群已成功创建")
        except Exception as e:
            logger.error(f"创建PostgreSQL集群时出错: {e}")
            return
            
        # 启动新的PostgreSQL集群
        try:
            logger.info("正在启动新的PostgreSQL集群...")
            run_command([
                "sudo", "systemctl", "start", f"postgresql@{self.pg_version}-main.service"
            ])
            logger.info("新的PostgreSQL集群已成功启动")
        except Exception as e:
            logger.error(f"启动PostgreSQL集群时出错: {e}")
    
    def fix_shared_memory_issue(self):
        """修复数据库共享内存段落错误"""
        try:
            # 编辑 /etc/systemd/logind.conf 文件
            logind_conf_path = "/etc/systemd/logind.conf"
            
            with open(logind_conf_path, "r") as file:
                lines = file.readlines()
                
            # 检查 RemoveIPC 是否已存在，并修改或添加
            with open(logind_conf_path, "w") as file:
                for line in lines:
                    if line.strip().startswith("RemoveIPC"):
                        file.write("RemoveIPC=no\n")
                    else:
                        file.write(line)
                        
                # 如果 RemoveIPC 没有被找到，添加该行
                if not any(line.strip().startswith("RemoveIPC") for line in lines):
                    file.write("RemoveIPC=no\n")
                    
            logger.info(f"已成功修改 {logind_conf_path} 文件")
            logger.info("正在重新加载systemd-logind.service")
            run_command(["sudo", "systemctl", "restart", "systemd-logind.service"])
            
            # 重新启动 PostgreSQL 数据库
            logger.info("正在重启PostgreSQL数据库...")
            run_command(["sudo", "systemctl", "restart", f"postgresql@{self.pg_version}-main.service"])
            logger.info("PostgreSQL数据库已成功重启")
        except Exception as e:
            logger.error(f"修复共享内存段错误时出错: {e}") 